import { ImageRawData } from "@ugeez/frontend-commons/lib/types";
import { getGlobalConfig } from "@ugeez/frontend-commons";
import { randomId } from "@ugeez/frontend-commons/lib/utils";

export const parallel = async (promiseTasks: Promise<any | void>[]): Promise<any[]> => {
    return new Promise((resolve, reject) => {
        const doneTasks: any[] = [];
        let doneNum = 0;

        const checkDone = () => {
            if (doneNum >= promiseTasks.length) {
                let results: any = [];
                for (let task of doneTasks) {
                    if (task.error) {
                        reject(task.error);
                        return;
                    }
                    results.push(task.result);
                }
                resolve(results);
            }
        }

        promiseTasks.forEach((p, i) => {
            let task: any = { result: undefined, error: undefined };
            doneTasks[i] = task;
            p.then((...rest) => {
                task.result = rest;
                doneNum ++;
                checkDone();
            }).catch(err => {
                task.error = err;
                doneNum ++;
                checkDone();
            });
        });
    });
}

export const genCaptchaImageUrl = (sessId: string) => {
    const { setting } = getGlobalConfig();
    let fullUrl: string = setting.apiGateway;
    if (!fullUrl.endsWith('/')) {
        fullUrl = fullUrl + '/';
    }
    fullUrl = fullUrl + 'lbj/naruto/system/captcha/image?sessId=' + sessId;
    return fullUrl;
}

export const loadImage = (url:string): Promise<string> => {
    return new Promise((resolve, reject) => {
        const img = new Image();
        img.crossOrigin = 'Anonymous';
        img.onload = () => {

            const canvas = document.createElement('CANVAS') as HTMLCanvasElement;
            const ctx = canvas.getContext('2d');
            let dataURL: string = '';
            canvas.height = img.naturalHeight;
            canvas.width = img.naturalWidth;
            if (ctx) ctx.drawImage(img, 0, 0);
            dataURL = canvas.toDataURL();
            resolve(dataURL);
        };
        img.onerror = (e) => {
            reject(new Error(e.toString()));
        };
        img.src = url;
    })
}

export const copyText = (text: string) => {
    /* Get the text field */
    const con = document.createElement('INPUT') as HTMLInputElement;
    con.id = 'copy-' + randomId();
    con.style.position = 'fixed';
    con.style.zIndex = '0';
    con.style.top = '-1000px';
    con.style.left = '0px';
    document.body.appendChild(con);

    con.value = text;
    
    /* Select the text field */
    con.select();
    con.setSelectionRange(0, 99999); /* For mobile devices */
    
    /* Copy the text inside the text field */
    document.execCommand("copy");

    const input = document.body.querySelector('#' + con.id);
    if (input) document.body.removeChild(input);
}

export const exactImagesFromRichText = (html: string): string[] => {
    if (!html) return [];
    const matches = html.match(/<img.+\s?(\/){0,1}>/img);
    if (!matches || matches.length < 1) return [];

    const files: string[] = [];
    for (let match of matches) {
        const holder = document.createElement('DIV');
        holder.innerHTML = match;
        const img = holder.firstChild as HTMLImageElement;
        if (!img || !img.src) continue;
        files.push(img.src);
    }
    return files;
}

export const checkHtmlTextIsEmpty = (input: string): boolean => {
    const holder = document.createElement('DIV');
    holder.innerHTML = input;
    if (holder.innerText.trim().length < 1) {
        return true;
    }
    return false;
}

export const fileSizeText = (size: number): string => {
    //小于1 K
    if (size / 1024 <= 1) {
        return '1 K';
    }
    //小于1 M
    if (size / (1024 * 1024) <= 1) {
        return Math.round(size / 1024) + ' K';
    }
    //小于1 G
    if (size / (1024 * 1024 * 1024) <= 1) {
        return Number(size / (1024 * 1024)).toFixed(2).replace('.00', '') + ' M';
    }

    return Number(size / (1024 * 1024 * 1024)).toFixed(2).replace('.00', '') + ' G';
}

export const chooseImage = (): Promise<ImageRawData[]> => {
    return new Promise(resolve => {

        const dispose = (input: HTMLInputElement) => {
            input.removeEventListener('change', onSelectFile);
            document.body.removeChild(input);
        }

        const onSelectFile = (e) => {
            const input = e.target as HTMLInputElement;
            const file = e.target.files[0] as File;
            if (!file) {
                console.log('canceled...');
                resolve([]);
                return;
            }

            const reader = new FileReader();
            reader.onload = (e) => {
                if (e && e.target && e.target.result) {
                    const raw: ImageRawData = {
                        data: e.target.result as string,
                        type: file.type,
                    };
                    dispose(input);
                    resolve([ raw ]);
                }
            }
            reader.readAsDataURL(file);

        }
        
        const inputId = 'photo-uploader';
        let input = document.getElementById(inputId) as HTMLInputElement;
        if (input) {
            dispose(input);
        }
        input = document.createElement('INPUT') as HTMLInputElement;
        input.type = 'file';
        input.id = inputId;
        input.style.visibility = 'hidden';
        input.style.position = 'fixed';
        input.style.left = '-20000px';
        input.style.top = '-20000px';
        input.addEventListener('change', onSelectFile);
        document.body.appendChild(input);
    
        input.click();
    });
}

export const chooseFile = ({ maxNum = 1, accept = '', maxSize = 0 }): Promise<File[]> => {
    return new Promise((resolve, reject) => {

        const dispose = (input: HTMLInputElement) => {
            input.removeEventListener('change', onSelectFile);
            document.body.removeChild(input);
        }

        const onSelectFile = (e) => {
            const files: File[] = e.target.files;
            if (files.length > maxNum) {
                reject(new Error(`最多只能选择${maxNum}个文件`));
            } else {
                if (maxSize > 0) {
                    const mb = 1024 * 1024;
                    for (let file of files) {   
                        if (file.size > maxSize * mb) {
                            reject(new Error(`文件大小不能超过 ${maxSize} MB`));
                            return;
                        }
                    }
                }

                resolve(files);
            }
        }
        
        const inputId = 'file-uploader';
        let input = document.getElementById(inputId) as HTMLInputElement;
        if (input) {
            dispose(input);
        }
        input = document.createElement('INPUT') as HTMLInputElement;
        input.type = 'file';
        input.id = inputId;
        input.style.visibility = 'hidden';
        input.style.position = 'fixed';
        input.style.left = '-20000px';
        input.style.top = '-20000px';
        if (accept) {
            input.setAttribute('accept', accept);
        }
        if (maxNum > 1) {
            input.setAttribute('multiple', 'multiple');
        }
        input.addEventListener('change', onSelectFile);
        document.body.appendChild(input);
    
        input.click();
    });
}

export const cdn = (file: string): string => {
    const { setting } = getGlobalConfig();
    let url = setting.cdn;
    if (url.endsWith('/')) {
        url = url.substr(0, url.length - 1);
    }
    if (file.startsWith('/')) {
        return url + file;
    }
    return url + '/' + file;
}
